<?php

/**
 * Description of YamlParser
 *
 * @author Abdelmohsen
 */
class YamlParser extends sfYamlParser
{

    /**
     * @method parseFile write new yaml schema file
     * @param <string> $pFileName
     * @param <array> $pSoftDeleteArray
     * @author Abdelmohsen
     */
    private $_yamlArray;

    public function parseFile($pFileName, $pSoftDeleteArray=null)
    {

        $this->_yamlArray = $this->parse(file_get_contents($pFileName));

        $_yamlArrayFile = array();

        $this->removeGuardPluginTables();

        //prepare yaml array
        foreach ($this->_yamlArray as $_tableName => $_node)
        {

            if (isset($_node['columns']['deleted_at']))
            {
                $_node = $this->addSoftDeleteBehavior($_node);
            }

            if (isset($_node['columns']['created_at']) && isset($_node['columns']['updated_at']))
            {
                $_node = $this->addTimestampBehaviour($_node);
            }

            // detect NestedSet behavior
            if (isset($_node['columns']['parent_id'], $_node['columns']['lft'], $_node['columns']['rgt'], $_node['columns']['level']))
            {
                $_node = $this->addNestedSetBehaviour($_node);
            }

            $_yamlArrayFile[$_tableName] = $_node;
        }

        $this->_yamlArray = $_yamlArrayFile;
    }

    /**
     * @method addTimestampBehaviour add timestamp behaviour (created_at,updetaed_at) and flag to add softdelete or not
     * @param <array> $pNode
     * @return array node array after modification
     * @author Abdelmohsen
     *
     */
    private function addTimestampBehaviour($pNode)
    {

        unset($pNode['columns']['created_at']);
        unset($pNode['columns']['updated_at']);

        $pNode['actAs'][] = 'Timestampable';

        return $pNode;
    }

    public function addSoftDeleteBehavior($pNode)
    {

        unset($pNode['columns']['deleted_at']);

        $pNode['actAs'][] = 'SoftDelete';

        return $pNode;
    }

    /**
     *
     * @param   array $pNode
     * @return  array node array after modification
     * @author  Karim El Shendy
     */
    public function addNestedSetBehaviour(array $pNode)
    {
        unset($pNode['columns']['parent_id']);
        unset($pNode['columns']['lft']);
        unset($pNode['columns']['rgt']);
        unset($pNode['columns']['level']);

        $pNode['actAs']['NestedSet'] = array('hasManyRoots' => true, 'rootColumnName' => 'parent_id');

        return $pNode;
    }

    /**
     * @author Micheal Mouner
     * send array of arrays by tbales names
     * @param Array $refrenceClasses
     * @return Array 
     */
    public function addManyToManyRelations($refrenceClasses)
    {

        $manyRelations = array();
        $schema = $this->_yamlArray;


        foreach ($schema as $tableName => $tableInfo)
        {
            if (isset($tableInfo['relations']))
            {
                $tablesNames = array_keys($tableInfo['relations']);
                $relationData = array_values($tableInfo['relations']);
                foreach ($refrenceClasses as $key => $relation)
                {

                    if (in_array($relation[0], $tablesNames) && in_array($relation[1], $tablesNames))
                    {
                        if ($tableInfo['relations'][$relation[0]]['type'] == "one" && $tableInfo['relations'][$relation[1]]['type'] == "one")
                        {
                            if (!isset($manyRelations[$relation[0]][$relation[1] . "s"]))
                            {
                                $manyRelations[$relation[0]][$relation[1] . "s"] = array(
                                    'class' => $relation[1],
                                    'refClass' => $tableName,
                                    'local' => $tableInfo['relations'][$relation[0]]['local'],
                                    'foreign' => $tableInfo['relations'][$relation[1]]['local'],
                                    'foreignAlias' => $relation[0] . "s",
                                );
                            } else
                            {
                                echo 'fff';
                                $repeated[$relation[1] . "s"] = array($relation[0], $relation[1] . "s");
                                $manyRelations[$relation[0]][$relation[1] . "s" . $tableName] = array(
                                    'class' => $relation[1],
                                    'refClass' => $tableName,
                                    'local' => $tableInfo['relations'][$relation[0]]['local'],
                                    'foreign' => $tableInfo['relations'][$relation[1]]['local'],
                                    'foreignAlias' => $relation[0] . "s" . $tableName,
                                );
                            }
                        }
                    }
                }
            }
        }

//        foreach ($repeated as $key => $relation)
//        {
//            $array = $manyRelations[$relation[0]][$relation[1]];
//            unset($manyRelations[$relation[0]][$relation[1]]);
//            $manyRelations[$relation[0]][$relation[1] . $array['refClass']] = $array;
//        }
        foreach ($manyRelations as $tableName => $tableManyRelations)
        {
            $schema[$tableName]['relations'] = array_merge($schema[$tableName]['relations'], $tableManyRelations);
        }
        $this->_yamlArray = $schema;
        return $schema;
    }

    public function dumpTofile($pFileName)
    {


        $_dumper = new sfYamlDumper();
        $_yamlFile = $_dumper->dump($this->_yamlArray, 20000);
        file_put_contents($pFileName, $_yamlFile);
    }

    private function removeGuardPluginTables()
    {

        $haystackarray = array(
            'SfGuardForgotPassword',
            'SfGuardGroup',
            'SfGuardGroupPermission',
            'SfGuardPermission',
            'SfGuardRememberKey',
            'SfGuardUser',
            'SfGuardUserGroup',
            'SfGuardUserPermission',
        );


        foreach ($this->_yamlArray as $tableName => $content)
        {
            if (in_array($tableName, $haystackarray))
            {
                unset($this->_yamlArray[$tableName]);
            } else
            {
                if (isset($content['relations']))
                {
                    foreach ($content['relations'] as $relationName => $relation)
                    {
                        if (in_array($relationName, $haystackarray))
                        {
                            unset($this->_yamlArray[$tableName]['relations'][$relationName]);
                            $this->_yamlArray[$tableName]['relations'][strtolower(substr($relationName, 0, 1)) . substr($relationName, 1)] = $relation;
                        }
                    }
                }
            }
        }
    }

}
